/**
 * Created by husong on 18/04/2018.
 */
import {ByteArray} from "./ByteArray";
import {protoMapping} from "./proto/mapping";

export class BasicMessage<T> {
  /**
   * 消息内容
   */
  private _content: T;
  message: number;
  messageId: number;
  senderType: number = 0;
  senderId: number = 0;
  receiverType: number = 0;
  receiverId: number = 0;
  messageLength: number;
  time: number = 0;

  /**
   * 把ByteArray 解析成 BasicMessage
   * @param {ByteArray} byteArray
   * @returns {T}
   */
  decode(byteArray: ByteArray): T {
    this.messageLength = byteArray.readInt();
    this.message = byteArray.readInt();
    this.messageId = byteArray.readInt();
    this.senderType = byteArray.readInt();
    if (this.senderType !== 0) {
      this.senderId = byteArray.readInt();
    }
    this.receiverType = byteArray.readInt();
    if (this.receiverType !== 0) {
      this.receiverId = byteArray.readInt();
    }
    this.time = byteArray.readInt();

    const contentByte = byteArray.buffer.slice(byteArray.position);
    const clazz = protoMapping.ID_TO_MSG.get(this.message)
    if (clazz) {
      const uint8Array = new Uint8Array(contentByte)
      this._content = clazz.decode(uint8Array)
    } else {
      this._content = <T><any>contentByte;
    }
    return this._content;
  }

  /**
   * 把该 BasicMessage encode成ArrayBuffer
   * @returns {ArrayBuffer}
   */
  encode(): ArrayBuffer {
    //不加入len的array
    const byteArray = new ByteArray(new ArrayBuffer(300));
    byteArray.writeInt(this.message)
    byteArray.writeInt(this.messageId)
    byteArray.writeInt(this.senderType)
    if (this.senderType !== 0) {
      byteArray.writeInt(this.senderId);
      // this.senderId.encode(byteArray)
    }
    byteArray.writeInt(this.receiverType)
    if (this.receiverType) {
      byteArray.writeInt(this.receiverId);
    }
    if (!this.time) {
      this.time = 10000;
    }
    byteArray.writeInt(this.time);
    byteArray._writeUint8Array(this.content);
    const req = new ByteArray(new ArrayBuffer(byteArray.length + 4))
    req.writeInt(byteArray.position);
    req.writeBytes(byteArray)
    return req.buffer;
  }

  set content(value: T) {
    this._content = value;
    // const msgId = MSG_ID_MAPPING.get(this._content.constructor);
    // if (msgId) {
    //   this.message = msgId
    // }
  }

  get content(): T {
    return this._content;
  }

  static decode(buffer: ArrayBuffer) {
    const b = new ByteArray(buffer)
    const basicMessage = new BasicMessage();
    basicMessage.decode(b);
    return basicMessage;
  }
}